#include "StdAfx.h"
#include "Hal.h"

Hal::Hal(void)
{
	InitializeCriticalSection(&m_Section);
}

Hal::~Hal(void)
{
	DeleteCriticalSection(&m_Section);
}

bool Hal::Init(CString fileName, DWORD idThread,UINT msg)
{
	fileName_ = fileName;
	fileHandle_ = CreateFile(fileName);
	//GD_DBG_LOG("fileHandle_ value: %d",fileHandle_);
	if (INVALID_HANDLE_VALUE == fileHandle_)
	{
		fileHandle_ = NULL;
		GD_DBG_LOG("create %s fail, err code: %d",fileName.GetBuffer(),GetLastError());
		return false;
	}
	idThread_ = idThread;
	msg_ = msg;
	AfxBeginThread(ReadThread,this);

	return true;
}

void Hal::Read(void* buf, DWORD len, DWORD& realLen)
{
	ReadFile(fileHandle_,buf,len,&realLen,NULL);
}

bool Hal::Write(void* buf, DWORD len, DWORD& realLen)
{
	return !!WriteFile(fileHandle_,buf,len,&realLen,NULL);
}

/*static*/ UINT Hal::ReadThread(LPVOID param)
{
	
	Hal* pThis = static_cast<Hal*>(param);
	pThis->ReadWorker();
	
	return 0;
}

void Hal::ReadWorker()
{
	GD_DBG_LOG("create %s file read thread",fileName_.GetBuffer());
	BYTE buf[512] = {0};
	DWORD len = 0;
	while (fileHandle_ != INVALID_HANDLE_VALUE)
	{
		//DWORD dwEvtmsk = 0;
		
		//BOOL res = WaitCommEvent(fileHandle_,&dwEvtmsk,0);
		bool res = WriteReadEvent(fileHandle_);
		//GD_DBG_LOG("%s WaitCommEvent res %d, err code: %d, evemsk: 0x%08x",fileName_.GetBuffer(),res,GetLastError(),dwEvtmsk);
		/*::PostThreadMessage(idThread_,msg_,0,0);
		Sleep(500);*/
		Read(buf,512,len);
		AddMsg(buf,len);
		//GD_DUMP("read hal data",buf,len);
		::PostThreadMessage(idThread_,msg_,0,0);
		
	}
}

void Hal::AddMsg(byte* buf, size_t len)
{
	Msg msg;
	memcpy(msg.buf,buf,len);
	msg.len = len;

	EnterCriticalSection(&m_Section);
	list_.push_back(msg);
	LeaveCriticalSection(&m_Section); 

}
void Hal::GetMsg(byte* buf, size_t& len)
{
	EnterCriticalSection(&m_Section);

	Msg& msg = list_.front();
	memcpy(buf,msg.buf,msg.len);
	len = msg.len;

	list_.pop_front();

	LeaveCriticalSection(&m_Section); 
}
void Hal::PopMsg()
{
	EnterCriticalSection(&m_Section);
	list_.pop_front();
	LeaveCriticalSection(&m_Section); 
}

HANDLE Hal::CreateFile( CString fileName )
{
	GD_DBG_LOG("hal create file %s",fileName.GetBuffer());
	return ::CreateFile(fileName, GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
}

bool Hal::WriteReadEvent( HANDLE handle )
{
	DWORD dwEvtmsk = 0;
	return !!WaitCommEvent(fileHandle_,&dwEvtmsk,0);
}